package com.hsurosy.hsuchain.nft.user.infrastructure.interceptor;

import com.github.houbb.sensitive.core.api.SensitiveUtil;
import com.hsurosy.hsuchain.nft.user.domain.entity.convertor.UserConvertor;
import com.hsurosy.hsuchain.nft.web.vo.Result;
import com.hsurosy.hsuchain.nft.api.user.response.data.UserInfo;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 脱敏响应体处理类
 *
 * @Author Hsu琛君珩
 * @Date 2024-10-05 18:13
 * @Description
 * @Version: v1.0.0
 */
@ControllerAdvice
public class SensitiveResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    /**
     * 判断是否支持特定返回类型的响应体
     *
     * @param returnType 返回值的类型
     * @param converterType 消息转换器的类型
     * @return 如果返回类型是 Result 类型，则返回 true，表明支持处理此类响应体
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 只对 Result 类型的返回值执行处理逻辑，这里可以根据需要调整判断条件
        return Result.class.isAssignableFrom(returnType.getParameterType());
    }

    /**
     * 在响应体写入之前执行脱敏处理
     *
     * @param body 返回的响应体对象
     * @param returnType 返回值的类型
     * @param selectedContentType 选择的内容类型
     * @param selectedConverterType 选择的消息转换器类型
     * @param request 当前请求对象
     * @param response 当前响应对象
     * @return 处理后的响应体对象
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        // 如果返回的对象是 Result 类型且包含 UserInfo 数据，则进行脱敏处理
        if (body instanceof Result && ((Result<?>) body).getData() instanceof UserInfo) {
            Result<UserInfo> result = (Result<UserInfo>) body;  // 获取响应体中的用户信息
            UserInfo userInfo = result.getData();  // 从 Result 中提取 UserInfo 对象

            // 将 UserInfo 转换为 User 实体
            User user = UserConvertor.INSTANCE.mapToEntity(userInfo);

            // 使用 SensitiveUtil 对 User 对象中的敏感信息进行脱敏处理
            user = SensitiveUtil.desCopy(user);

            // 将脱敏后的 User 对象转换回 UserInfo 对象并设置到结果中
            result.setData(UserConvertor.INSTANCE.mapToVo(user));

            // 返回处理后的结果
            return result;
        }
        // 如果不是 UserInfo 类型，则不做处理，直接返回原始响应体
        return body;
    }
}
